Imports System
Imports System.Collections.Generic
Imports ASPNET.StarterKit.DataAccessLayer
Imports _2gs_datewizard

Namespace ASPNET.StarterKit.BusinessLogicLayer

    Public Class TimeEntry

        Private _CreatorUserName As String
        Private _Category As Category
        Private _CategoryId As Integer
        Private _DateCreated As DateTime
        Private _Description As String
        Private _Duration As Decimal
        Private _Id As Integer
        Private _Project As Project
        Private _ReportedDate As DateTime
        Private _UserName As String

        Public Sub New(ByVal creatorUserName As String, ByVal categoryId As Integer, ByVal duration As Decimal, ByVal reportedDate As DateTime, ByVal userName As String)

            Me.New(creatorUserName, categoryId, DefaultValues.GetDateTimeMinValue(), String.Empty, duration, DefaultValues.GetTimeEntryIdMinValue(), reportedDate, userName)

        End Sub

        Public Sub New(ByVal creatorUserName As String, ByVal categoryId As Integer, ByVal dateCreated As DateTime, ByVal description As String, ByVal duration As Decimal, ByVal id As Integer, ByVal reportedDate As DateTime, ByVal userName As String)

            If String.IsNullOrEmpty(creatorUserName) Then
                Throw New NullReferenceException("creatorUserName")
            End If

            If categoryId <= DefaultValues.GetCategoryIdMinValue() Then
                Throw New ArgumentOutOfRangeException("categoryId")
            End If

            If duration <= DefaultValues.GetDurationMinValue() Then
                Throw New ArgumentOutOfRangeException("duration")
            End If

            If reportedDate <= DefaultValues.GetDateTimeMinValue() Then
                Throw New ArgumentOutOfRangeException("reportedDate")
            End If

            If String.IsNullOrEmpty(userName) Then
                Throw New NullReferenceException("userName")
            End If

            Me._CreatorUserName = creatorUserName
            Me._CategoryId = categoryId
            Me._DateCreated = dateCreated
            Me._Description = description
            Me._Duration = duration
            Me._Id = id
            Me._ReportedDate = reportedDate
            Me._UserName = userName

        End Sub

        ' PROPERTIES

        Public ReadOnly Property CreatorUserName() As String

            Get
                If String.IsNullOrEmpty(Me._CreatorUserName) Then
                    Return String.Empty
                Else
                    Return Me._CreatorUserName
                End If
            End Get

        End Property

        Public Property CategoryId() As Integer

            Get
                Return Me._CategoryId
            End Get

            Set(ByVal value As Integer)

                Dim currentProject As Project
                If Me._Category Is Nothing Then
                    Me._Category = Category.GetCategoryByCategoryId(Me._CategoryId)
                    If Me._Category Is Nothing Then
                        Throw New NullReferenceException("Can not find existing category")
                    End If
                End If

                currentProject = Project.GetProjectById(_Category.ProjectId)
                If currentProject Is Nothing Then
                    Throw New NullReferenceException("NewProject is not a valid one")
                End If

                Dim newProject As Project
                Dim newCategory As Category = Category.GetCategoryByCategoryId(value)

                If newCategory Is Nothing Then
                    Throw New NullReferenceException("NewCategory is not a valid one")
                End If

                newProject = Project.GetProjectById(newCategory.ProjectId)
                If newProject Is Nothing Then
                    Throw New NullReferenceException("NewProject is not a valid one")
                End If

                If newProject.Id = currentProject.Id Then
                    Me._CategoryId = value
                    Me._Category = Nothing
                End If

            End Set

        End Property

        Public ReadOnly Property CategoryName() As String

            Get
                If Me._Category Is Nothing Then
                    Me._Category = Category.GetCategoryByCategoryId(CategoryId)
                    If Me._Category Is Nothing Then
                        Return String.Empty
                    End If
                End If
                Return Me._Category.Name
            End Get

        End Property

        Public ReadOnly Property DateCreated() As DateTime

            Get
                Return Me._DateCreated
            End Get

        End Property

        Public Property Description() As String

            Get
                If String.IsNullOrEmpty(Me._Description) Then
                    Return String.Empty
                Else
                    Return Me._Description
                End If
            End Get

            Set(ByVal value As String)
                Me._Description = value
            End Set

        End Property

        Public Property Duration() As Decimal

            Get
                Return Me._Duration
            End Get

            Set(ByVal value As Decimal)
                Me._Duration = value
            End Set

        End Property

        Public ReadOnly Property Id() As Integer

            Get
                Return Me._Id
            End Get

        End Property

        Public Property ReportedDate() As DateTime

            Get
                Return Me._ReportedDate
            End Get

            Set(ByVal value As DateTime)
                Me._ReportedDate = value
            End Set

        End Property

        Public ReadOnly Property ProjectName() As String

            Get
                If Me._Category Is Nothing Then
                    Me._Category = Category.GetCategoryByCategoryId(Me.CategoryId)
                    If Me._Category Is Nothing Then
                        Return String.Empty
                    End If
                End If

                Me._Project = Project.GetProjectById(_Category.ProjectId)
                If _Project Is Nothing Then
                    Return String.Empty
                End If

                Return Me._Project.Name
            End Get

        End Property

        Public ReadOnly Property ProjectID() As Integer

            Get
                If Me._Category Is Nothing Then
                    Me._Category = Category.GetCategoryByCategoryId(Me.CategoryId)
                    If Me._Category Is Nothing Then
                        Return String.Empty
                    End If
                End If

                Me._Project = Project.GetProjectById(_Category.ProjectId)
                If _Project Is Nothing Then
                    Return String.Empty
                End If

                Return Me._Project.Id
            End Get

        End Property

        Public Property UserName() As String

            Get
                If String.IsNullOrEmpty(Me._UserName) Then
                    Return String.Empty
                Else
                    Return Me._UserName
                End If
            End Get

            Set(ByVal value As String)
                Me._UserName = value
            End Set

        End Property

        ' METHODS

        Public Function Delete() As Boolean

            If Me.Id > DefaultValues.GetProjectIdMinValue() Then
                Return DataAccessHelper.GetDataAccess().DeleteTimeEntry(Me.Id)
            Else
                Return False
            End If

        End Function

        Public Function Save() As Boolean

            Dim DALLayer As DataAccess = DataAccessHelper.GetDataAccess()

            If Me.Id <= DefaultValues.GetProjectIdMinValue() Then
                Dim TempId As Integer = DALLayer.CreateNewTimeEntry(Me)
                If TempId > DefaultValues.GetTimeEntryIdMinValue() Then
                    Me._Id = TempId
                    Return True
                Else
                    Return False
                End If
            Else
                Return DALLayer.UpdateTimeEntry(Me)
            End If

        End Function

        ' STATIC METHODS

        Public Shared Function DeleteTimeEntry(ByVal Id As Integer) As Boolean

            If Id <= DefaultValues.GetCategoryIdMinValue() Then
                Throw New ArgumentOutOfRangeException("Id")
            End If

            Return DataAccessHelper.GetDataAccess().DeleteTimeEntry(Id)

        End Function

        Public Shared Function GetAllTimeEntries() As List(Of TimeEntry)

            Return DataAccessHelper.GetDataAccess().GetAllTimeEntries()

        End Function

        Public Shared Function GetTimeEntries(ByVal projectId As Integer, ByVal userName As String) As List(Of TimeEntry)

            If projectId <= DefaultValues.GetProjectIdMinValue() Then
                Return New List(Of TimeEntry)()
            End If

            If String.IsNullOrEmpty(userName) Then
                Return New List(Of TimeEntry)()
            End If

            Return DataAccessHelper.GetDataAccess().GetTimeEntries(projectId, userName)

        End Function

        Public Shared Function GetTimeEntryById(ByVal timeEntryId As Integer) As TimeEntry

            If timeEntryId <= DefaultValues.GetTimeEntryIdMinValue() Then
                Return Nothing
            End If

            Return DataAccessHelper.GetDataAccess().GetTimeEntryById(timeEntryId)

        End Function

        Public Shared Function GetTimeEntriesByUserNameAndDates(ByVal userName As String, ByVal startingDate As DateTime, ByVal endDate As DateTime) As List(Of TimeEntry)

            If String.IsNullOrEmpty(userName) Then
                Return New List(Of TimeEntry)()
            End If

            Return DataAccessHelper.GetDataAccess().GetTimeEntriesByUserNameAndDates(userName, startingDate, endDate)

        End Function

        Public Shared Function GetTimeEntriesByUserNameAndWeekOf(ByVal userName As String, ByVal SelectedDate As DateTime) As List(Of TimeEntry)

            If String.IsNullOrEmpty(userName) Then
                Return New List(Of TimeEntry)()
            End If

            'Find beging and end of Week
            Dim startingDate As DateTime
            Dim endDate As DateTime
            Dim WeekOf As New C_DateWizard(SelectedDate)
            startingDate = WeekOf.FirstDateInWeek
            endDate = WeekOf.LastDateInWeek

            Return DataAccessHelper.GetDataAccess().GetTimeEntriesByUserNameAndDates(userName, startingDate, endDate)

        End Function

        Public Shared Function UpdateTimeEntry(ByVal Id As Integer, ByVal CategoryName As String, ByVal Description As String, ByVal Duration As Decimal, ByVal ReportedDate As DateTime, ByVal UserName As String) As Boolean

            If String.IsNullOrEmpty(CategoryName) Then
                Throw New NullReferenceException("categoryName")
            End If

            Dim t As TimeEntry = TimeEntry.GetTimeEntryById(Id)
            If t Is Nothing Then
                Return False
            End If

            Dim currentCategory As Category = Category.GetCategoryByCategoryId(t.CategoryId)
            If currentCategory Is Nothing Then
                Return False
            End If

            Dim currentProject As Project = Project.GetProjectById(currentCategory.ProjectId)
            If currentProject Is Nothing Then
                Return False
            End If

            Dim newCategory As Category = Category.GetCategoryByCategoryNameandProjectId(CategoryName, currentProject.Id)
            If newCategory Is Nothing Then
                Return False
            End If

            If Not t Is Nothing Then
                t.Description = Description
                t.Duration = Duration
                t.ReportedDate = ReportedDate
                t.CategoryId = newCategory.Id
                t.UserName = UserName
                Return t.Save()
            Else
                Return False
            End If

        End Function

        Public Shared Function UpdateTimeEntry(ByVal Id As Integer, ByVal CategoryName As String, ByVal Description As String, ByVal Duration As Decimal, ByVal ReportedDate As DateTime, ByVal UserName As String, ByVal CategoryId As Integer) As Boolean

            ' We throw away CatagoryName as it is only used in the edit grid for binding the dropdown now

            'If String.IsNullOrEmpty(CategoryName) Then
            '    Throw New NullReferenceException("categoryName")
            'End If

            Dim t As TimeEntry = TimeEntry.GetTimeEntryById(Id)
            If t Is Nothing Then
                Return False
            End If

            Dim currentCategory As Category = Category.GetCategoryByCategoryId(t.CategoryId)
            If currentCategory Is Nothing Then
                Return False
            End If

            Dim currentProject As Project = Project.GetProjectById(currentCategory.ProjectId)
            If currentProject Is Nothing Then
                Return False
            End If

            Dim newCategory As Category = Category.GetCategoryByCategoryId(CategoryId)
            If newCategory Is Nothing Then
                Return False
            End If

            If Not t Is Nothing Then
                t.Description = Description
                t.Duration = Duration
                t.ReportedDate = ReportedDate
                t.CategoryId = newCategory.Id
                t.UserName = UserName
                Return t.Save()
            Else
                Return False
            End If

        End Function

    End Class

End Namespace
